/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙，邂逅框架梦]
 * 
 * https://zhiqim.org/project/zhiqim_framework/zhiqim_kernel.htm
 *
 * Zhiqim Kernel is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
package org.zhiqim.kernel.global;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.zhiqim.kernel.Z;
import org.zhiqim.kernel.ZhiqimI18n;
import org.zhiqim.kernel.logging.Logs;
import org.zhiqim.kernel.model.maps.LinkedMapSV;
import org.zhiqim.kernel.model.maps.MapSV;
import org.zhiqim.kernel.service.Service;
import org.zhiqim.kernel.util.Asserts;
import org.zhiqim.kernel.util.Validates;

/**
 * 全局服务管理器
 *
 * @version v8.0.1 @author zgzou 2022年2月12日 新建与整理
 */
public class Serv
{
  //全局服务列表
    private final MapSV<Service> map = new LinkedMapSV<>();
    
    /********************************************************************************/
    //系统服务设置和获取等
    /********************************************************************************/
    
    /** 判断是否有服务信息 */
    public boolean has(String id)
    {
        return map.containsKey(id);
    }
    
    /** 获取配置的服务信息 */
    public Service get(String id)
    {
        return map.get(id);
    }
    
    /** 获取配置的服务信息，并强制转换 */ @SuppressWarnings("unchecked")
    public <T> T get(Class<T> cls, String id)
    {
        if (Validates.isEmptyBlank(id))
            return get(cls);
        
        Service service = map.get(id);
        return (service != null && cls == service.getClass())?(T)service:null;
    }
    
    /** 获取类名相同的服务第一个 */ @SuppressWarnings("unchecked") 
    public <T> T get(Class<T> cls)
    {
        for (Service service : map.values())
        {
            if (cls == service.getClass())
                return (T)service;
        }
        
        return null;
    }
    
    /** 获取类名相同的服务第$(index)个 */ @SuppressWarnings("unchecked")
    public <T> T get(Class<T> cls, int idx)
    {
        int index = 0;
        for (Service service : map.values())
        {
            if (cls != service.getClass())
                continue;
            
            if (index == idx)
                return (T)service;
            
            index++;
        }
        
        return null;
    }
    
    /** 获取类名相同的服务列表 */ @SuppressWarnings("unchecked")
    public <T> List<T> list(Class<T> cls)
    {
        List<T> list = new ArrayList<>();
        for (Service service : map.values())
        {
            if (cls == service.getClass())
                list.add((T)service);
        }
        
        return Collections.unmodifiableList(list);
    }
    
    /** 增加服务 */
    public void add(Service service)
    {
        Asserts.asserts(!map.containsKey(service.getId()), ZhiqimI18n.globalDuplicateServiceNotSupported);
        map.put(service.getId(), service);
    }
    
    /** 移除服务 */
    public void remove(String id)
    {
        map.remove(id);
    }
    
    /** 关闭所有服务 */
    public void closeAll()
    {
        List<Service> serviceList = new ArrayList<>(map.values());
        
        //关闭操作，从最后一个开始
        for (int i=serviceList.size()-1;i>=0;i--)
        {
            Service service = serviceList.get(i);
            
            try
            {
                service.destroy();
            }
            catch(Exception e)
            {
                Logs.error("系统[%s]-版本[%s]退出时服务[%s]销毁异常", e, Z.conf().getName(), Z.conf().getVersion(), service.getId());
            }
        }
        
        //清理表
        serviceList.clear();
        map.clear();
    }
    
}
